package com.fsp.service;

import com.fsp.dao.SupermanMapper;
import com.fsp.pojo.Superman;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * @author fushengping
 * @className SupermanServiceImpl
 * @description
 * @date 2021/11/30 9:38
 */
@Service
public class SupermanServiceImpl implements SupermanService {
    @Resource
    private SupermanMapper supermanMapper;

    /**
     * 使用递归查询所有节点并进行设置
     * @return
     */
    @Override
    public List<Superman> getSupermanAll1() {
        //查询出所有角色的根节点
        List<Superman> rootSupermenList = getSupermanRoot();
        //分别查出根节点的子节点并进行设置
        for (Superman superman : rootSupermenList) {
            //通过递归查询父节点相应的子节点
            List<Superman> children = queryChildrenByParentId(superman);
            superman.setChildren(children);
        }

        return rootSupermenList;
    }

    /*查询角色的根节点*/
    public List<Superman> getSupermanRoot() {
        Superman superman = new Superman();
        superman.setPid(0);
        return supermanMapper.select(superman);
    }

    /**
     * 递归查询父节点对应的子节点
     */
    public List<Superman> queryChildrenByParentId(Superman parent) {
        Superman superman = new Superman();
        superman.setPid(parent.getId());
        //通过查询父节点从而查询出对应的子节点
        List<Superman> children = supermanMapper.select(superman);
        for (Superman child : children) {
            List<Superman> grandChildren = queryChildrenByParentId(child);
            //父节点将子节点设置进入list<Superman>中
            child.setChildren(grandChildren);
        }
        return children;
    }


    /**
     * 法二：循环读取设置
     * @return
     */
    @Override
    public List<Superman> getSupermanAll2() {
        //作为最后的返回结果
        List<Superman> list = new ArrayList<>();
        //全量查询所有节点
        List<Superman> supermanList = supermanMapper.selectAll();
        for (Superman left : supermanList) {
            for (Superman right : supermanList) {
                if (left.getId() == right.getPid()) {
                    left.getChildren().add(right); //这里默认把left设置为父节点
                }
            }
            //将第一级的数据存入其中,根节点的pid都为0，根节点的id都不相同
            if (left.getPid() == 0) { //将父节点是1的根节点存入返回
                list.add(left);
            }
        }
        return list;
    }

    /**
     * 通过map集合进行父子节点配置
     * @return
     */
    @Override
    public List<Superman> getSupermanAll3() {
        //作为最后的返回结果
        List<Superman> list = new ArrayList<>();
        //查询所有节点
        List<Superman> data = supermanMapper.selectAll();
        //定义map,用来转存list
        HashMap<Integer, Superman> hashMap = new HashMap<>();

        //定义左侧节点
        for (Superman superman : data) {
            //将所有节点全部存入hashMap中
            hashMap.put(superman.getId(),superman);
        }

        for (Superman child : data) {
            if (child.getPid() == 0) { //将根节点存入list数组中
                list.add(child);
            } else {
                //通过hashMap的索引，找到相应的父节点(相当于不断的往根节点中循环存入child)
                Superman parent = hashMap.get(child.getPid()); //取出子节点对应的父节点
                parent.getChildren().add(child); //父子节点的匹配就完成了
            }
        }
        return list;
    }

    /**
     * 根据pid分步查询（实际开发最常用）
     * @param pid
     * @return
     */
    @Override
    public List<Superman> getSupermanByPid(Integer pid) {
        Superman superman = new Superman();
        superman.setPid(pid);
        List<Superman> supermanList = supermanMapper.select(superman);
        return supermanList;
    }
}
